package com.binlog.core.handler;

import com.binlog.util.SpringContextUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


/**
 * Handler factory
 *
 * @description: handler工厂
 * @author: cyj
 * @date 2022 -05-13 16:45:44
 *
 *
 */
@Slf4j
public class HandlerFactory {

    private HandlerFactory() {
    }

    /**
     * Po status change base process map
     */
    private volatile static Map<String, CommonEventListenerHandler> commonEventListenerHandlerMap;


    /*
     * 初始化
     * */
    public static void init() {
        if (null != commonEventListenerHandlerMap) {
            return;
        }
        Lock initLock = new ReentrantLock();
        initLock.lock();
        try {
            Map<String, CommonEventListenerHandler> commonEventListenerHandlerInitMap = SpringContextUtils.getApplicationContext().getBeansOfType(CommonEventListenerHandler.class);
            if (null != commonEventListenerHandlerInitMap) {
                commonEventListenerHandlerMap = new HashMap<>();
                commonEventListenerHandlerInitMap.values().forEach(commonEventListenerHandler -> {
                    if (StringUtils.isEmpty(commonEventListenerHandler.getTableName())) {
                        return;
                    }
                    commonEventListenerHandlerMap.put(String.format("%s-%s", commonEventListenerHandler.getDatesource(), commonEventListenerHandler.getTableName()), commonEventListenerHandler);
                });
            }
        } catch (Exception e) {
            log.warn("handler工厂初始化失败: {}", e.getMessage());
        } finally {
            initLock.unlock();
        }
    }

    /**
     * Gets bean 获取具体实例
     *
     * @return the bean
     */
    public static CommonEventListenerHandler getInstance(String table, String schema) {
        String key = String.format("%s-%s", schema, table);
        init();
        if (!commonEventListenerHandlerMap.containsKey(key)) {
            throw new RuntimeException("表：" + key + ", handler 未实现");
        }
        return commonEventListenerHandlerMap.get(key);
    }

}
